﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using DialectSoftware.Networking;

namespace WebFabricator.org.Management
{
    public delegate HELOResult Helo();

    //http://stackoverflow.com/questions/2604826/multicast-messages-to-multiple-clients-on-the-same-machine
    //http://stackoverflow.com/questions/2143531/problem-recieving-udp-packets-send-to-127-0-0-1-when-using-so-reuseaddr
    //http://stackoverflow.com/questions/9120050/connecting-two-udp-clients-to-one-port-send-and-receive *****100%
    public class SLSMPServer
    {

        public const int PORT = 1300;

        //public const int PORT = 1900;
        //public const string IP = "239.255.1.2";

        BroadcastServer _server;
        //MulticastServer _server;

        public SLSMPServer()
        {
            _server = new BroadcastServer();
            _server.Receive += new AsyncNetworkCallBack(Receive);
            _server.ErrorHandler += new AsyncNetworkErrorCallBack(ErrorHandler);

            //_server = new MulticastServer();
            //_server.ErrorHandler += new MulticastServer.MulticastServerErrorHandler(ErrorHandler);
            //_server.ErrorHandler += new BroadcastServer.BroadcastServerErrorHandler(ErrorHandler);
        }

        public void ListenBegin()
        {
            _server.Listen(PORT);
            //_server.Listen(IPAddress.Parse(IP), PORT);
        }

        void ErrorHandler(AsyncNetworkAdapter state, Exception e)
        {
            try
            {
                System.Diagnostics.Debug.WriteLine(e.Message);
            }
            catch
            {

            }
        }

        void Receive(AsyncNetworkAdapter adapter)
        {
            try
            {
                
                try
                {
                    IEnumerable<SLSMPRequest> requests = SLSMPRequest.Parse(adapter);
                    requests.ForEach(request =>
                    {
                        SLSMPResponse response = null;
                        switch (request.Method)
                        {
                            case SLSMP.HELO:
                                if (OnHelo != null)
                                {
                                    response = new SLSMPResponse(request, SLSMP.ACK, OnHelo().ToString());
                                }
                                else
                                {
                                    response = new SLSMPResponse(request, SLSMP.ACK, null);
                                }
                                break;
                            default:
                                throw new NotImplementedException(request.Method.ToString());

                        }
                        //_server.Respond(adapter, response.ToByteArray());
                        _server.Send(adapter, response.ToByteArray());
                    });
                }
                catch
                {
                }
                
            }
            catch
            {

            }
            finally
            {
                
            }
        }

        public event Helo OnHelo;
       
    }
}
